package com.kehutong.work.order.manage.service;

import java.net.URLEncoder;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;
import org.coraframework.inject.Inject;
import org.coraframework.json.JSONArray;
import org.coraframework.json.JSONObject;
import org.coraframework.logger.Logger;
import org.coraframework.logger.LoggerFactory;
import org.coraframework.mvc.http.ReqMapping;
import org.coraframework.mvc.http.result.Result;
import org.coraframework.mvc.webservice.WebService;
import org.coraframework.orm.Pool;
import org.coraframework.orm.jdbc.JdbcSession;
import org.coraframework.orm.jdbc.Page;
import org.coraframework.orm.jdbc.execute.entity.FindPage;
import org.coraframework.orm.util.Enums;
import org.coraframework.util.IDGenerate;
import org.coraframework.util.Objects;
import org.coraframework.util.time.TimeUtil;
import com.kehutong.common.DoveClient;
import com.kehutong.common.Java8TimeUtils;
import com.kehutong.common.dto.UniformSendReqDto;
import com.kehutong.common.enums.MessageBusinessEnum;
import com.kehutong.common.enums.OperateType;
import com.kehutong.common.enums.TemplateType;
import com.kehutong.common.urlconfig.WebUrlConfig;
import com.kehutong.common.util.TemplateReplaceUtil;
import com.kehutong.common.util.Token;
import com.kehutong.work.order.manage.entity.WorkOrderManage;
import com.kehutong.work.order.manage.entity.WorkOrderManageRecord;
import com.kehutong.work.order.manage.entity.WorkOrderManageReminders;
import com.kehutong.work.order.manage.entity.WorkOrderManageType;
import com.kehutong.work.order.manage.enums.DoorToDoorEnum;
import com.kehutong.work.order.manage.enums.EmergencyStateEnum;
import com.kehutong.work.order.manage.enums.WorkOrderHandleStateEnum;
import com.kehutong.work.order.manage.enums.WorkOrderStateEnum;

@WebService("/work/order/manage/service")
public class WorkOrderManageService {

    private static Logger logger = LoggerFactory.getLogger(WorkOrderManageService.class);

    @Inject
    private JdbcSession jdbcSession;
    @Inject
    private DoveClient doveClient;
    @Inject
    private WebUrlConfig webUrlConfig;

    @ReqMapping("/app/count")
    public Object appCount(JSONObject jsonObject) {
        // 1001投诉，1002报修
        int complaintCount = jdbcSession.findArray(WorkOrderManage.class)
                                    .eq(jsonObject,"communityNo","createUserNo")
                                    .eq("typeNo", 1001)
                                    .eq("deleted", false)
                                    .eq("userCreate", true)
                                    .exe()
                                    .size();

        int repairCount = jdbcSession.findArray(WorkOrderManage.class)
                                     .eq(jsonObject,"communityNo","createUserNo")
                                     .eq("typeNo", 1002)
                                     .eq("deleted", false)
                                     .eq("userCreate", true)
                                     .exe()
                                     .size();

        int appraisalCount = jdbcSession.findArray(WorkOrderManage.class)
                                        .eq(jsonObject,"communityNo","createUserNo")
                                        .eq("userAppraisal", true)
                                        .eq("deleted", false)
                                        .eq("userCreate", true)
                                        .exe()
                                        .size();
        JSONObject result = new JSONObject();
        result.put("complaintCount", complaintCount);
        result.put("repairCount", repairCount);
        result.put("appraisalCount", appraisalCount);
        return Result.success(result);
    }

    public Page<WorkOrderManage> listPage(JSONObject jsonObject, String uuid, boolean userCreate) {
        FindPage<WorkOrderManage> findPage = jdbcSession.findPage(WorkOrderManage.class);

        // 1全部工单，2我发起的，3提交给我的，4抄送给我的
        int orderType = jsonObject.getIntValue("orderType");
        if (orderType == 1) {
            findPage.markBegin();
            findPage.eq("createUserNo", uuid).or();
            if (userCreate) {
                findPage.isNull("handleEmployeeNo").or();
            }
            findPage.like("handleEmployeeNo", uuid).or();
            findPage.like("submitToMeNo", uuid).or();
            findPage.markEnd();
        } else if (orderType == 2) {
            findPage.eq("createUserNo", uuid);
        } else if (orderType == 3) {
            findPage.like("submitToMeNo", uuid);
        } else if (orderType == 4) {
            findPage.like("noticeEmployeeNo", uuid);
        } else {
            // continue
        }

        // 提交时间
        String startCreateTime =jsonObject.getString("startCreateTime");
        String endCreateTime =jsonObject.getString("endCreateTime");
        if (Objects.nonEmpty(startCreateTime) && Objects.nonEmpty(endCreateTime)) {
            findPage.maxEq("createTime", startCreateTime);
            findPage.minEq("createTime", endCreateTime);
        }
        // 等待时长
        // 管理后台
        LocalDateTime now = LocalDateTime.now();
        Integer waitHour =jsonObject.getInteger("waitHour");
        if (Objects.nonNull(waitHour)) {
            if (waitHour > 7*24) {
                findPage.minEq("createTime", now.plusHours(-waitHour));
            } else {
                findPage.maxEq("createTime", now.plusHours(-waitHour));
            }
            // findPage.eq("workOrderState", WorkOrderStateEnum.ING);
        }
        // 企微端
        Integer startWaitHour =jsonObject.getInteger("startWaitHour");
        Integer endWaitHour =jsonObject.getInteger("endWaitHour");
        if (Objects.nonNull(startWaitHour) && Objects.nonNull(endWaitHour)) {
            findPage.maxEq("createTime", now.plusHours(-endWaitHour))
                    .minEq("createTime", now.plusHours(-startWaitHour));
                    // .eq("workOrderState", WorkOrderStateEnum.ING);
        } else if (Objects.nonNull(startWaitHour)){
            findPage.maxEq("createTime", now.plusHours(-startWaitHour));
                    // .eq("workOrderState", WorkOrderStateEnum.ING);
        } else {
            // continue
        }
        // 处理时间
        String startHandleTime =jsonObject.getString("startHandleTime");
        String endHandleTime =jsonObject.getString("endHandleTime");
        if (Objects.nonEmpty(startHandleTime) && Objects.nonEmpty(endHandleTime)) {
            findPage.maxEq("finishTime", startHandleTime);
            findPage.minEq("finishTime", endHandleTime);
        }
        JSONArray departments = jsonObject.getJSONArray("departments");
        if (Objects.nonEmpty(departments)) {
            // 提交部门
            try {
                //  1.远程调用部门获取该部门下员工信息
                JSONObject result = doveClient.post("/basic/employee/service/list", http -> {
                    JSONObject body = new JSONObject();
                    body.put("department", departments);
                    body.put("pageNo", 1);
                    body.put("pageSize", 1000000);
                    http.setBody(body.toString());
                });
                JSONArray data = result.getJSONObject("data")
                                       .getJSONArray("list");
                //  2.查找
                findPage.markBegin();
                for (int i = 0; i < data.size(); i++) {
                    JSONObject employeeJson = (JSONObject) data.get(i);
                    JSONArray departJsonArray = employeeJson.getJSONArray("department");
                    if (Objects.isEmpty(departJsonArray)) {
                        continue;
                    }
                    for (int j = 0; j < departJsonArray.size(); j++) {
                        String depart = String.valueOf(departJsonArray.get(j));
                        findPage.like("createUserDepart", depart).or();
                    }
                }
                findPage.markEnd().and();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }

        // 提交人员
        JSONArray createUsers = jsonObject.getJSONArray("createUsers");
        if(Objects.nonEmpty(createUsers)) {
            findPage.markBegin();
            for (Object createUser : createUsers){
                findPage.like("createUserNo", createUser);
            }
            findPage.markEnd().and();
        }
        // 处理人员
        JSONArray handleUsers = jsonObject.getJSONArray("handleUsers");
        if(Objects.nonEmpty(handleUsers)) {
            findPage.markBegin();
            for (Object handleUser : handleUsers){
                findPage.like("handleEmployeeNo", handleUser);
            }
            findPage.markEnd().and();
        }

        JSONArray workOrderStateList = jsonObject.getJSONArray("workOrderStateList");
        if (Objects.nonEmpty(workOrderStateList)) {
            findPage.in("workOrderState", workOrderStateList);
        }

        String name = jsonObject.getString("name");
        if (Objects.nonEmpty(name)) {
            findPage.markBegin();
            findPage.like( "name", name).or();
            findPage.like("content", name).or();
            findPage.markEnd();
        }

        findPage.eq(jsonObject, "typeNo", "workOrderState", "emergency", "userAppraisal", "communityNo");
        findPage.eq("deleted", false);
        findPage.order("createTime", "desc");

        return findPage.page(jsonObject).exe();
    }

    public Page<WorkOrderManage> listAppPage(JSONObject jsonObject, String uuid) {
        FindPage<WorkOrderManage> findPage = jdbcSession.findPage(WorkOrderManage.class);

        // 1全部工单，2我发起的，3提交给我的，4抄送给我的
        int orderType = jsonObject.getIntValue("orderType");
        if (orderType == 1) {
            findPage.markBegin();
            findPage.eq("createUserNo", uuid).or();
            findPage.isNull("handleEmployeeNo").or();
            findPage.like("handleEmployeeNo", uuid).or();
            findPage.like("submitToMeNo", uuid).or();
            findPage.markEnd();
        } else if (orderType == 2) {
            findPage.eq("createUserNo", uuid);
        } else if (orderType == 3) {
            findPage.markBegin();
            findPage.isNull("handleEmployeeNo").or();
            findPage.like("submitToMeNo", uuid).or();
            findPage.markEnd();
        } else if (orderType == 4) {
            findPage.like("noticeEmployeeNo", uuid);
        } else {
            // continue
        }

        // 提交时间
        String startCreateTime =jsonObject.getString("startCreateTime");
        String endCreateTime =jsonObject.getString("endCreateTime");
        if (Objects.nonEmpty(startCreateTime) && Objects.nonEmpty(endCreateTime)) {
            findPage.maxEq("createTime", startCreateTime);
            findPage.minEq("createTime", endCreateTime);
        }
        // 等待时长
        LocalDateTime now = LocalDateTime.now();
        // 企微端
        Integer startWaitHour =jsonObject.getInteger("startWaitHour");
        Integer endWaitHour =jsonObject.getInteger("endWaitHour");
        if (Objects.nonNull(startWaitHour) && Objects.nonNull(endWaitHour)) {
            findPage.maxEq("createTime", now.plusHours(-endWaitHour))
                    .minEq("createTime", now.plusHours(-startWaitHour));
        } else if (Objects.nonNull(startWaitHour)){
            findPage.min("createTime", now.plusHours(-startWaitHour));
        } else {
            // continue
        }
        // 处理时间
        String startHandleTime =jsonObject.getString("startHandleTime");
        String endHandleTime =jsonObject.getString("endHandleTime");
        if (Objects.nonEmpty(startHandleTime) && Objects.nonEmpty(endHandleTime)) {
            findPage.maxEq("finishTime", startHandleTime);
            findPage.minEq("finishTime", endHandleTime);
        }

        // 处理人员
        JSONArray handleUsers = jsonObject.getJSONArray("handleUsers");
        if(Objects.nonEmpty(handleUsers)) {
            findPage.markBegin();
            for (Object handleUser : handleUsers){
                findPage.like("handleEmployeeNo", handleUser);
            }
            findPage.markEnd().and();
        }

        JSONArray workOrderStateList = jsonObject.getJSONArray("workOrderStateList");
        if (Objects.nonEmpty(workOrderStateList)) {
            findPage.in("workOrderState", workOrderStateList);
        }

        String name = jsonObject.getString("name");
        if (Objects.nonEmpty(name)) {
            findPage.markBegin();
            findPage.like( "name", name).or();
            findPage.like("content", name).or();
            findPage.markEnd();
        }

        findPage.eq(jsonObject, "typeNo", "workOrderState", "emergency", "communityNo");
        findPage.eq("deleted", false);
        findPage.order("createTime", "desc");

        Page<WorkOrderManage> page = findPage.page(jsonObject).exe();

        if (Objects.nonEmpty(page.getList())) {
            page.getList().forEach(e -> {
                e.setTokenUserCreate(uuid.equals(e.getCreateUserNo()));
                e.setTokenUserHandle(e.getHandleEmployeeNo().contains(uuid));
            });
        }

        return page;
    }

    public Object search(String uuid, JSONObject jsonObject){
        FindPage<WorkOrderManage> findPage = jdbcSession.findPage(WorkOrderManage.class);

        String name = jsonObject.getString("name");

        if (Objects.isEmpty(name)) {
            return Result.error(0, "请输入关键字");
        }
        if (Objects.nonEmpty(name)) {
            findPage.markBegin();
            findPage.like( "name", name).or();
            findPage.like("content", name).or();
            findPage.markEnd();
        }

        String searchType = jsonObject.getString("searchType");
        if (Objects.isEmpty(searchType)) {
            return Result.error(0, "请选择搜索类型");
        }
        if ("1".equals(searchType)) {
            findPage.like("submitToMeNo", uuid);
        } else if ("2".equals(searchType)) {
            findPage.like("createUserNo", uuid);
        } else if ("3".equals(searchType)) {
            findPage.like("noticeEmployeeNo", uuid);
        } else {
            // continue
            // Objects.isEmpty(searchType)
        }
        findPage.eq("deleted", false);

        return Result.success(findPage.page(jsonObject).exe());
    }

    public Object assign(Token token, JSONObject json, WorkOrderManage order) {
        if (checkFinalState(order.getWorkOrderState())) {
            return Result.error(0, "已达到最终状态，不允许继续操作");
        }
        try {
            // 设置必要权限
            setHandleEmployee(order, token.getUuid(), token.getUsername());
        } catch (Exception e) {
            e.printStackTrace();
            return Result.error(0, "工单创建失败");
        }
        json.putAll(buildHandleUserJson(order, token.getUuid(), token.getUsername()));
        String recordId = insertRecord(json, order, WorkOrderHandleStateEnum.ASSIGN, true, false);
        order.setWorkOrderState(WorkOrderStateEnum.ING);
        order.setRecordId(recordId);
        jdbcSession.updateById(order);

        sendAssign(order);

        return Result.success();
    }

    private void sendAssign(WorkOrderManage order) {
        List<String> handleEmployee = order.getHandleEmployeeNo();
        handleEmployee.forEach(e -> {
            try {
                msgUniformSend(order, e, TemplateType.WO_B_CREATE_SEND, false);
            } catch (Exception exception) {
                exception.printStackTrace();
            }
        });
    }

    public JSONObject getCommunityById(String id) throws Exception {
        JSONObject result = doveClient.post("/basic/community/service/get", http->{
            http.addParam("id", id);
        });

        JSONObject data = result.getJSONObject("data");

        if (Objects.isNull(data)) {
            return null;
        }

        return data;
    }

    public Object save(WorkOrderManage manage, Token token, boolean userCreate) {
        if (Objects.isEmpty(manage.getCommunityNo())
            || Objects.isEmpty(manage.getTypeNo())
            || Objects.isEmpty(manage.getOneClassifyNo())
            || Objects.isEmpty(manage.getContent())
            || Objects.isNull(manage.getEmergency())
            || Objects.isNull(manage.getDoorToDoor())
            || (!userCreate && Objects.isEmpty(manage.getHandleEmployeeNo()))
        ) {
            return Result.error(0, "请填写必填参数");
        }

        if (userCreate && Objects.isEmpty(manage.getBuildNo())) {
            return Result.error(0, "请先绑定房屋");
        }
        manage.setWorkOrderState(WorkOrderStateEnum.ING);
        if (userCreate){
            if (Objects.nonEmpty(manage.getBuildNo())){
                JSONObject buildJson = listEmployeeByHouseNo(manage.getBuildNo(), token.getCompanyNo());
                if (Objects.isEmpty(manage.getCommunityNo())) {
                    manage.setCommunityNo(buildJson.getString("communityNo"));
                }
                JSONArray employeeNoArray = buildJson.getJSONArray("employeeNos");
                if (Objects.nonEmpty(employeeNoArray)){
                    List<String> employeeNos = JSONObject.parseArray(employeeNoArray.toJSONString(), String.class);
                    if (Objects.nonEmpty(employeeNos)) {
                        manage.setHandleEmployeeNo(employeeNos);
                    } else {
                        manage.setWorkOrderState(WorkOrderStateEnum.PRE_ASSIGNED);
                    }
                } else {
                    manage.setWorkOrderState(WorkOrderStateEnum.PRE_ASSIGNED);
                }
            }
        } else {
            JSONObject employeeJson = getEmployeeById(token.getUuid());
            if (Objects.nonNull(employeeJson)) {
                if (Objects.nonEmpty(employeeJson.getJSONArray("department")))
                    manage.setCreateUserDepart(String.valueOf(employeeJson.getJSONArray("department").get(0)));
                if (Objects.nonEmpty(employeeJson.getJSONArray("departmentName")))
                    manage.setCreateUserDepartName(String.valueOf(employeeJson.getJSONArray("departmentName").get(0)));
            }
        }
        manage.setCompanyNo(token.getCompanyNo());
        manage.setUserCreate(userCreate);
        manage.setCreateUserNo(token.getUuid());
        if (Objects.isEmpty(manage.getCreateUserName())) {
            manage.setCreateUserName(token.getUsername());
        }

        if (Objects.isEmpty(manage.getTypeName())) {
            WorkOrderManageType type = Pool.get(WorkOrderManageType.class, manage.getTypeNo());
            manage.setTypeName(type.getName());
        }
        if (Objects.nonEmpty(manage.getTwoClassifyName())) {
            manage.setName(manage.getTwoClassifyName());
        } else {
            manage.setName(manage.getOneClassifyName());
        }

        // 设置必要权限
        try {
            setHandleEmployee(manage, null, null);
            setDepart(manage);
        } catch (Exception e) {
            e.printStackTrace();
            return Result.error(0, "工单创建失败");
        }

        JSONObject jsonObject = buildHandleUserJson(manage, manage.getCreateUserNo(), manage.getCreateUserName());
        jsonObject.put("handlePositionTitle", manage.getHandlePositionTitle());
        jsonObject.put("avatar", manage.getAvatar());
        String recordId = insertRecord(jsonObject, manage, WorkOrderHandleStateEnum.CREATE, false, userCreate);
        manage.setRecordId(recordId);

        jdbcSession.insert(manage);

        if (Objects.nonEmpty(manage.getFileList())) {
            try {
                // 统一附件管理
                doveClient.post("/basic/annex/service/list/save", (http) -> {
                    JSONObject body = new JSONObject();
                    body.put("uuid", token.getUuid());
                    body.put("username", token.getUsername());
                    body.put("fileList", manage.getFileList());
                    body.put("businessType", "1300");
                    body.put("businessId", manage.getId());
                    http.setBody(body.toJSONString());
                });
            } catch (Exception e) {
                logger.error(e.getMessage(), e);
            }
        }

        // 消息推送
        // B端：发起人提交工单或原处理人转交工单
        manage.getHandleEmployeeNo().forEach(e ->{
            try {
                msgUniformSend(manage, e, TemplateType.WO_B_CREATE_SEND, false);
            } catch (Exception exception) {
                logger.error(exception.getMessage(), exception);
            }
        });

        try {
            // 1001投诉，1002报修
            if ("1002".equals(manage.getTypeNo()) && manage.isUserCreate()){
                //新增客户轨迹-发起报修
                doveClient.post("/auth/accountOperateLog/service/add", (http) -> {
                    JSONObject body = new JSONObject();
                    body.put("accountNo",manage.getCreateUserNo());
                    body.put("type", OperateType.INITIATE_REPAIR.getId());
                    body.put("desc", "发起报修");
                    body.put("createBy", token.getUuid());
                    body.put("createName", token.getUsername());
                    body.put("companyNo",token.getCompanyNo());
                    body.put("companyName",token.getCompanyName());
                    http.setBody(body.toJSONString());
                });
            } else if ("1001".equals(manage.getTypeNo()) && manage.isUserCreate()) {
                //新增客户轨迹-发起投诉
                doveClient.post("/auth/accountOperateLog/service/add", (http) -> {
                    JSONObject body = new JSONObject();
                    body.put("accountNo",manage.getCreateUserNo());
                    body.put("type", OperateType.INITIATE_COMPLAINT.getId());
                    body.put("desc", "发起投诉");
                    body.put("createBy", token.getUuid());
                    body.put("createName", token.getUsername());
                    body.put("companyNo",token.getCompanyNo());
                    body.put("companyName",token.getCompanyName());
                    http.setBody(body.toJSONString());
                });
            } else {
                // continue
            }


        } catch (Exception e){
            logger.error(e.getMessage(), e);
        }



        List<String> handleEmployee = manage.getHandleEmployeeNo();
        if (Objects.nonEmpty(handleEmployee)) {
            handleEmployee.forEach(e -> notifyEmployee("1", e, manage.getCreateUserNo(), manage.getCreateUserName(), manage.getName(), manage.getId()));
        }
        List<String> noticeEmployee = manage.getNoticeEmployeeNo();
        if (Objects.nonEmpty(noticeEmployee)) {
            noticeEmployee.forEach(e -> notifyEmployee("2", e, manage.getCreateUserNo(), manage.getCreateUserName(), manage.getName(), manage.getId()));
        }

        return Result.success();
    }
    private void msgUniformSend(WorkOrderManage manage, String uuid, TemplateType templateType, boolean userCreate) throws Exception {
        msgUniformSend(manage, uuid, templateType, null, userCreate);
    }

    private void msgUniformSend(WorkOrderManage manage, String uuid, TemplateType templateType, List<String> phoneList, boolean userCreate) throws Exception {
        // 获取消息推送配置文件
        JSONObject configJson = doveClient.post("/crm/message/global/config/service/get", (http) -> {
            http.addParam("templateType", templateType.getId());
        });

        if (configJson.getIntValue("code") == 200) {
            UniformSendReqDto dto = getUniformSendReqDto(manage, uuid, templateType, phoneList, configJson.getJSONObject("data"), userCreate);
            // 消息推送
            doveClient.post("/crm/message/service/uniformSend", (http) -> {
                http.addParam("temp", JSONObject.toJSONString(dto));
            });
        }
    }

    private UniformSendReqDto getUniformSendReqDto(WorkOrderManage manage, String uuid, TemplateType templateType, List<String> phoneList, JSONObject dataJson, boolean userCreate) throws Exception {
        UniformSendReqDto dto = new UniformSendReqDto();
        dto.setMsgId(manage.getId());
        dto.setBusinessTypeId(MessageBusinessEnum.MSG_WORK_ORDER.getId());
        dto.setTemplateTypeId(templateType.getId());
        dto.setCompanyNo(manage.getCompanyNo());
        dto.setUserCreate(userCreate);
        dto.setUuid(uuid);
        dto.setTitle(manage.getName());

        JSONObject inner = dataJson.getJSONObject("messageTemplateInner");
        if (dataJson.getBooleanValue("innerSend") && Objects.nonNull(inner)) {
            dto.setTitle(inner.getString("title"));
            dto.setInnerData(TemplateReplaceUtil.replace(inner.getString("content"), inner.getString("tagArray"), manage));
        }

        JSONObject app = dataJson.getJSONObject("messageTemplateApp");
        if (dataJson.getBooleanValue("appSend") && Objects.nonNull(app)) {
            dto.setTitle(app.getString("title"));
            dto.setAppData(TemplateReplaceUtil.replace(app.getString("content"), app.getString("tagArray"), manage));
            String param = "?tab=b";

            dto.setAppToUrl(webUrlConfig.getUrl("/web-app/?page=order/" + manage.getId() + "/2" + URLEncoder.encode(param, "UTF-8")));

        }

        JSONObject sms = dataJson.getJSONObject("messageTemplateSms");
        if (dataJson.getBooleanValue("smsSend") && Objects.nonNull(sms)) {
            if (Objects.nonEmpty(phoneList)){
                dto.setPhoneList(phoneList);
                dto.setSmsDataParams(TemplateReplaceUtil.listTencentSmsParam(sms.getString("content"), sms.getString("tagArray"), manage));
            } else {
                JSONObject jsonObject = doveClient.post("/kht-bin/auth/user/listPhone", http -> {
                    JSONObject temp = new JSONObject();
                    temp.put("id", Arrays.asList(uuid));
                    http.setBody(temp.toJSONString());
                });
                List<String> listPhone = JSONArray.parseArray(jsonObject.getString("data"), String.class);
                if (Objects.nonEmpty(listPhone)){
                    dto.setPhoneList(listPhone);
                    dto.setSmsDataParams(TemplateReplaceUtil.listTencentSmsParam(sms.getString("content"), sms.getString("tagArray"), manage));
                }
            }

        }

        String wxchatTemplate = dataJson.getString("wxchatTemplate");
        if (dataJson.getBooleanValue("wxchatSend") && Objects.nonNull(wxchatTemplate)) {
            dto.setWxChatData(getWxchatTemplate(templateType, manage));
            if (TemplateType.WO_C_SUCCESS == templateType){
                dto.setPageParam(String.format("id=%s&companyNo=%s", manage.getId(), manage.getCompanyNo()));
            } else if (TemplateType.WO_C_REPLY == templateType){
                dto.setPageParam(String.format("id=%s&companyNo=%s&tabsActive=1", manage.getId(), manage.getCompanyNo()));
            } else {

            }

        }

        return dto;
    }

    public void test(String id, String uuid, String type) throws Exception {
        TemplateType templateType = Enums.getEnum(TemplateType.class, type);

        WorkOrderManage manage = Pool.get(WorkOrderManage.class, id);

        UniformSendReqDto dto = new UniformSendReqDto();
        dto.setMsgId(manage.getId());
        dto.setBusinessTypeId(MessageBusinessEnum.MSG_WORK_ORDER.getId());
        dto.setTemplateTypeId(templateType.getId());
        dto.setCompanyNo(manage.getCompanyNo());
        dto.setUserCreate(manage.isUserCreate());
        dto.setUuid(uuid);
        dto.setTitle(manage.getName());

        dto.setWxChatData(getWxchatTemplate(templateType, manage));
        if (TemplateType.WO_C_SUCCESS == templateType){
            dto.setPageParam(String.format("id=%s&companyNo=%s", manage.getId(), manage.getCompanyNo()));
        } else if (TemplateType.WO_C_REPLY == templateType){
            dto.setPageParam(String.format("id=%s&companyNo=%s&tabsActive=1", manage.getId(), manage.getCompanyNo()));
        } else {

        }

        // 消息推送
        // doveClient.post1("/crm/message/service/test", (http) -> {
        //     // JSONObject dtoJson = (JSONObject) JSONObject.toJSON(dto);
        //     String dtoJson = JSONObject.toJSONString(dto);
        //     http.addParam("id", dtoJson);
        //     // http.setBody(dtoJson);
        // });
    }

    private String getWxchatTemplate(TemplateType templateType, WorkOrderManage manage){
        JSONObject data = new JSONObject();

        if(TemplateType.WO_C_SUCCESS == templateType){
            String address = "";
            if (Objects.nonEmpty(manage.getAddress())){
                address = manage.getAddress();
                if (Objects.nonEmpty(manage.getAddressDetail())){
                    address += manage.getAddressDetail();
                }
            } else {
                address = manage.getCommunityName();
            }

            data.put("first", buildMpMessageData("您的工单已处理完成"));
            // 工单编号
            data.put("keyword1", buildMpMessageData(manage.getId()));
            // 需求描述
            data.put("keyword2", buildMpMessageData(manage.getName()));
            // 需求时间
            data.put("keyword3", buildMpMessageData(Java8TimeUtils.parseString(manage.getCreateTime().toLocalDateTime())));
            // 需求地点
            data.put("keyword4", buildMpMessageData(address));
            // 需求状态
            data.put("keyword5", buildMpMessageData(manage.getWorkOrderState().getDesc()));

            data.put("remark", buildMpMessageData("祝您生活愉快！"));
            return data.toJSONString();
        } else {
            return null;
        }
    }

    private JSONObject buildMpMessageData(String value) {
        JSONObject json = new JSONObject();
        json.put("value", value);
        return json;
    }

    private void setDepart(WorkOrderManage manage) throws Exception {
        if (Objects.isEmpty(manage.getCommunityNo())) {
            return;
        }

        JSONObject communityJson = getCommunityById(manage.getCommunityNo());
        if (Objects.nonNull(communityJson)) {
            manage.setDepartmentNo(communityJson.getString("parent_id"));
            manage.setDepartmentName(communityJson.getString("parent_name"));
            JSONArray parentIdsArray = communityJson.getJSONArray("parent_ids");
            if (Objects.nonEmpty(parentIdsArray)) {
                manage.setDepartmentNos(JSONObject.parseArray(parentIdsArray.toJSONString(), String.class));
            }
        }
    }

    private JSONObject createNextEmployee(WorkOrderManage manage) {
        StringBuilder nextEmployeeNo = new StringBuilder();
        StringBuilder nextEmployeeName = new StringBuilder();
        for (int i = 0; i < manage.getHandleEmployeeNo().size(); i++) {
            if (i == manage.getHandleEmployeeNo().size() - 1) {
                nextEmployeeNo.append(manage.getHandleEmployeeNo().get(i));
            } else {
                nextEmployeeNo.append(manage.getHandleEmployeeNo().get(i)).append(",");
            }
        }
        for (int i = 0; i < manage.getHandleEmployeeName().size(); i++) {
            if (i == manage.getHandleEmployeeName().size() - 1) {
                nextEmployeeName.append(manage.getHandleEmployeeName().get(i));
            } else {
                nextEmployeeName.append(manage.getHandleEmployeeName().get(i)).append(",");
            }
        }
        JSONObject jsonObject = new JSONObject();
        jsonObject.put("nextUserNo", nextEmployeeNo.toString());
        jsonObject.put("nextUserName", nextEmployeeName.toString());
        return jsonObject;
    }

    /**
     * 通过id获取员工信息
     *
     * @param id
     * @return
     * @throws Exception
     */
    private JSONObject getEmployeeById(String id) {
        try {
            JSONObject object = doveClient.post("/basic/employee/service/get", (http) -> {
                JSONObject body = new JSONObject();
                body.put("id", id);

                http.setBody(body.toString());
            });
            if (object.getInteger("code") == 200) {
                return object.getJSONObject("data");
            } else {
                return null;
            }
        } catch (Exception e){
            logger.error(e.getMessage(), e);
            return null;
        }
    }

    private void setHandleEmployee(WorkOrderManage order, String uuid, String uuname) throws Exception {
        Set<String> handleEmployeeNameSet = new HashSet<>();
        Set<String> handleEmployeeDepartSet = new HashSet<>();
        Set<String> submitToMeSet = new HashSet<>(order.getSubmitToMeNo());
        Set<String> submitToMeNameSet = new HashSet<>(order.getSubmitToMeName());
        Set<String> authorityUserSet = new HashSet<>(order.getAuthorityUserList());

        if (Objects.nonEmpty(uuid)) {
            submitToMeSet.add(uuid);
            submitToMeNameSet.add(uuname);
            authorityUserSet.add(uuid);
        }

        JSONArray employeeJsonArray = remoteEmployeeList(order.getHandleEmployeeNo());
        for (int i = 0; i < employeeJsonArray.size(); i++) {
            JSONObject json = (JSONObject) employeeJsonArray.get(i);
            String employeeId = json.getString("id");
            String employeeName = json.getString("name");
            Set<String> departNameSet = json.getJSONArray("departmentName").stream().map(String::valueOf).collect(Collectors.toSet());
            handleEmployeeNameSet.add(employeeName);
            handleEmployeeDepartSet.addAll(departNameSet);
            submitToMeSet.add(employeeId);
            submitToMeNameSet.add(employeeName);
            authorityUserSet.add(employeeId);
        }

        order.setHandleEmployeeName(new ArrayList<>(handleEmployeeNameSet));
        order.setHandleDepartName(new ArrayList<>(handleEmployeeDepartSet));
        order.setSubmitToMeNo(new ArrayList<>(submitToMeSet));
        order.setSubmitToMeName(new ArrayList<>(submitToMeNameSet));
        order.setAuthorityUserList(new ArrayList<>(authorityUserSet));

    }

    private JSONArray remoteEmployeeList(List<String> employeeIds) throws Exception {
        if (Objects.isEmpty(employeeIds)) {
            return new JSONArray();
        }
        JSONObject result = doveClient.post("/basic/employee/service/list", http -> {
            JSONObject body = new JSONObject();
            body.put("id", employeeIds);
            body.put("pageNo", 1);
            body.put("pageSize", 1000000);
            http.setBody(body.toString());
        });

        return result.getJSONObject("data")
                               .getJSONArray("list");
    }

    private JSONObject listEmployeeByHouseNo(String houseNo, String companyNo) {
        try {
            JSONObject buildingResult = doveClient.post("/basic/building/service/get", (http) -> {
                Map<String, String> map =new HashMap<>();
                map.put("companyNo", companyNo);
                http.setHeaders(map);
                JSONObject body = new JSONObject();
                body.put("id", houseNo);
                http.setBody(body.toJSONString());
            });

            if (buildingResult.getIntValue("code")== 200) {
                JSONObject buildingJson=buildingResult.getJSONObject("data");
                if(Objects.nonNull(buildingJson)){
                    return buildingJson;
                }
            }
        } catch (Exception e) {
            logger.error(e.getMessage(), e);
            return new JSONObject();
        }
        return new JSONObject();
    }

    public Object delete(WorkOrderManage manage, String uuid) {
        if (Objects.nonEmpty(uuid) && Objects.nonNull(manage)) {
            synchronized (manage.getId().intern()) {
                List<String> authList = manage.getAuthorityUserList();
                authList.remove(uuid);
                manage.setAuthorityUserList(authList);
                jdbcSession.updateById(manage);
            }
        }

        return Result.success();
    }

    public Object detail(Token token, String id, boolean adminPage){
        WorkOrderManage order = Pool.get(WorkOrderManage.class, id);
        if (Objects.isNull(order)) {
            return Result.error(0, "工单不存在");
        }

        // if (!adminPage && !order.getAuthorityUserList().contains(token.getUuid())) {
        //     return Result.error(0, "您暂无权限查看此工单，工单ID：" + order.getId());
        // }

        List<WorkOrderManageRecord> recordList = jdbcSession.findArray(WorkOrderManageRecord.class)
                                                            .eq("workOrderId", id)
                                                            .order("createTime", "desc")
                                                            .exe();
        order.setRecordList(recordList);
        order.setReturnableEmployeeNo(order.getCreateUserNo());
        order.setReturnableEmployeeName(order.getCreateUserName());
        order.setTokenUserCreate(token.getUuid().equals(order.getCreateUserNo()));
        order.setTokenUserHandle(order.getHandleEmployeeNo().contains(token.getUuid()));

        return Result.success(order);
    }

    /**
     *
     * @param uuid 当前登录用户ID，含员工和用户
     * @param json
     * @return
     */
    public Object handleWorkOrder(String uuid, String uuName, JSONObject json, boolean userCreate){
        String id = json.getString("id");
        WorkOrderManage order = Pool.get(WorkOrderManage.class, id);
        if (Objects.isNull(order)) {
            return Result.error(0, "工单不存在");
        }

        // if (!uuid.equals(order.getCreateUserNo()) && order.getWorkOrderState() != WorkOrderStateEnum.ING) {
        //     return Result.error(0, "不能操作该工单");
        // }

        WorkOrderHandleStateEnum type = Enums.getEnum(WorkOrderHandleStateEnum.class, json.getJSONObject("handleState").getString("id"));
        List<String> handleEmployeeNoList = new ArrayList<>();
        List<String> handleEmployeeNameList = new ArrayList<>();
        String recordId;
        switch (type) {
            case EDIT:
                editWorkOrder(json, order, userCreate);
                return Result.success();
            case REVOKE:
                if (checkFinalState(order.getWorkOrderState())) {
                    return Result.error(0, "已达到最终状态，不允许继续操作");
                }
                // 生成撤销工单记录
                json.putAll(buildHandleUserJson(order, uuid, uuName));
                recordId = insertRecord(json, order, WorkOrderHandleStateEnum.REVOKE, false, userCreate);
                // 设置终态
                order.setWorkOrderState(WorkOrderStateEnum.REVOKE);
                handleEmployeeNoList.add(uuid);
                handleEmployeeNameList.add(uuName);
                order.setHandleEmployeeNo(handleEmployeeNoList);
                order.setHandleEmployeeName(handleEmployeeNameList);
                order.setFinishTime(LocalDateTime.now());
                break;
            case REFUND:
                if (checkFinalState(order.getWorkOrderState())) {
                    return Result.error(0, "已达到最终状态，不允许继续操作");
                }
                order.setWorkOrderState(WorkOrderStateEnum.REFUND);
                handleEmployeeNoList.add(uuid);
                handleEmployeeNameList.add(uuName);
                order.setHandleEmployeeNo(handleEmployeeNoList);
                order.setHandleEmployeeName(handleEmployeeNameList);
                // 生成退回工单记录
                json.put("nextUserNo", order.getCreateUserNo());
                json.put("nextUserName", order.getCreateUserName());
                json.put("handleUserNo", uuid);
                json.put("handleUserName", Objects.nonEmpty(json.getString("createUserName")) ? json.getString("createUserName") : uuName);
                recordId = insertRecord(json, order, WorkOrderHandleStateEnum.REFUND, false, userCreate);
                order.setFinishTime(LocalDateTime.now());
                break;
            case SEND:
                if (checkFinalState(order.getWorkOrderState())) {
                    return Result.error(0, "已达到最终状态，不允许继续操作");
                }
                // 设置转他人状态
                order.setWorkOrderState(WorkOrderStateEnum.SEND);
                handleEmployeeNoList.add(json.getString("nextEmployeeNo"));
                order.setHandleEmployeeNo(handleEmployeeNoList);
                handleEmployeeNameList.add(json.getString("nextEmployeeName"));
                order.setHandleEmployeeName(handleEmployeeNameList);

                json.putAll(buildHandleUserJson(order, uuid, uuName));
                // 生成转他人记录
                recordId = insertRecord(json, order, WorkOrderHandleStateEnum.SEND, false, userCreate);
                sendAssign(order);
                break;
            case SUCCESS:
                if (checkFinalState(order.getWorkOrderState())) {
                    return Result.error(0, "已达到最终状态，不允许继续操作");
                }
                if (order.isSignIn()) {
                    WorkOrderManageRecord recordTemp = Pool.get(WorkOrderManageRecord.class, order.getRecordId());
                    if (recordTemp.getHandleState() != WorkOrderHandleStateEnum.SIGN_IN) {
                        return Result.error(0, "请先完成外勤签到");
                    }
                }
                handleEmployeeNoList.add(uuid);
                handleEmployeeNameList.add(uuName);
                order.setHandleEmployeeNo(handleEmployeeNoList);
                order.setHandleEmployeeName(handleEmployeeNameList);
                json.putAll(buildHandleUserJson(order, uuid, uuName));
                // 生成成功工单记录
                recordId = insertRecord(json, order, WorkOrderHandleStateEnum.SUCCESS, false, userCreate);
                order.setWorkOrderState(WorkOrderStateEnum.SUCCESS);
                order.setFinishTime(LocalDateTime.now());

                JSONArray jsonArray = json.getJSONArray("fileList");
                if (Objects.nonEmpty(jsonArray)) {
                    try {
                        doveClient.post("/basic/annex/service/list/save", (http) -> {
                            JSONObject body = new JSONObject();
                            body.put("uuid", uuid);
                            body.put("username", uuName);
                            body.put("fileList", jsonArray);
                            body.put("businessType", "1300");
                            body.put("businessId", order.getId());
                            http.setBody(body.toJSONString());
                        });
                    } catch (Exception e) {
                        logger.error(e.getMessage(), e);
                    }
                }
                if (order.isUserCreate()) {
                    try {
                        if (Objects.nonEmpty(order.getCreatePhone())){
                            msgUniformSend(order, order.getCreateUserNo(), TemplateType.WO_C_SUCCESS, Arrays.asList(order.getCreatePhone()), order.isUserCreate());
                        } else {
                            msgUniformSend(order, order.getCreateUserNo(), TemplateType.WO_C_SUCCESS, order.isUserCreate());
                        }

                    } catch (Exception e) {
                        logger.error(e.getMessage(), e);
                    }
                }
                break;
            case SIGN_IN:
                if (checkFinalState(order.getWorkOrderState())) {
                    return Result.error(0, "已达到最终状态，不允许继续操作");
                }
                json.putAll(buildHandleUserJson(order, uuid, uuName));
                // 生成签到工单记录
                recordId = insertRecord(json, order, WorkOrderHandleStateEnum.SIGN_IN, true, userCreate);
                order.setSignInAddress(json.getString("address"));
                order.setSignInLng(json.getString("lng"));
                order.setSignInLat(json.getString("lat"));
                break;
            default:
                return Result.error(0, "请确认操作后，重试");
        }

        order.setRecordId(recordId);

        // 设置必要权限
        try {
            if (!userCreate) {
                setHandleEmployee(order, uuid, uuName);
            }
        } catch (Exception e) {
            logger.error(e.getMessage(), e);
            return Result.error(0, "操作失败");
        }

        jdbcSession.updateById(order);
        return Result.success();
    }

    private boolean checkFinalState(WorkOrderStateEnum orderStateEnum) {

        if (orderStateEnum == WorkOrderStateEnum.REFUND || orderStateEnum == WorkOrderStateEnum.REVOKE || orderStateEnum == WorkOrderStateEnum.SUCCESS) {
            return true;
        }
        return false;
    }

    private void editWorkOrder(JSONObject json, WorkOrderManage order, boolean userCreate) {
        if (order.getWorkOrderState() == WorkOrderStateEnum.ING) {
            // 编辑当前工单
            setWorkOrder(json, order);
            try {
                setDepart(order);
            }catch (Exception e) {
                logger.error(e.getMessage(), e);
            }
            JSONObject jsonObject = buildHandleUserJson(order, order.getCreateUserNo(), order.getCreateUserName());
            json.putAll(jsonObject);

            // 生成编辑工单记录
            String recordId = insertRecord(json, order, WorkOrderHandleStateEnum.EDIT, true, userCreate);
            order.setRecordId(recordId);

            // 设置部门
            Set<String> departSet = new HashSet<>();
            for (int i = 0; i < order.getHandleEmployeeNo().size(); i++) {
                JSONObject employeeJson = getEmployeeById(order.getHandleEmployeeNo().get(i));
                if (Objects.nonNull(employeeJson)) {
                    JSONArray depart = employeeJson.getJSONArray("departmentName");
                    if (Objects.nonEmpty(depart)){
                        departSet.addAll(JSONArray.parseArray(depart.toJSONString(), String.class));
                    }
                }
            }
            order.setHandleDepartName(new ArrayList<>(departSet));

            jdbcSession.updateById(order);

            List<String> handleEmployee = order.getHandleEmployeeNo();
            if (Objects.nonEmpty(handleEmployee)) {
                handleEmployee.forEach(e -> notifyEmployee("1", e, order.getCreateUserNo(), order.getCreateUserName(), order.getName(), order.getId()));
            }
            List<String> noticeEmployee = order.getNoticeEmployeeNo();
            if (Objects.nonEmpty(noticeEmployee)) {
                noticeEmployee.forEach(e -> notifyEmployee("2", e, order.getCreateUserNo(), order.getCreateUserName(), order.getName(), order.getId()));
            }
        } else{
            // 重新生成工单
            WorkOrderManage tempOrder = order;
            initWorkOrder(tempOrder);
            tempOrder.setCreateUserNo(order.getCreateUserNo());
            tempOrder.setCreateUserName(order.getCreateUserName());
            tempOrder.setCreateUserDepartName(order.getCreateUserDepartName());
            // 重置找管家
            if (userCreate) {
                if (Objects.nonEmpty(tempOrder.getHouseNo())){
                    JSONObject buildJson = buildEmployee(tempOrder.getBuildNo(), json.getString("companyNo"));
                    if (Objects.nonEmpty(buildJson.getJSONArray("employeeNos")))
                        tempOrder.setHandleEmployeeNo(buildJson.getJSONArray("employeeNos").stream().map(String::valueOf).collect(Collectors.toList()));
                    if (Objects.nonEmpty(buildJson.getJSONArray("employeeNames")))
                        tempOrder.setHandleEmployeeName(buildJson.getJSONArray("employeeNames").stream().map(String::valueOf).collect(Collectors.toList()));
                    if (Objects.nonEmpty(buildJson.getJSONArray("departs")))
                        tempOrder.setHandleDepartName(buildJson.getJSONArray("departs").stream().map(String::valueOf).collect(Collectors.toList()));
                }
            }

            setWorkOrder(json, tempOrder);
            try {
                setDepart(tempOrder);
            }catch (Exception e) {
                logger.error(e.getMessage(), e);
            }

            JSONObject jsonObject = buildHandleUserJson(tempOrder, order.getCreateUserNo(), order.getCreateUserName());
            json.putAll(jsonObject);
            // 创建新的工单记录
            String recordId = insertRecord(json, tempOrder, WorkOrderHandleStateEnum.CREATE, false, userCreate);
            tempOrder.setRecordId(recordId);

            // 设置部门
            Set<String> departSet = new HashSet<>();
            for (int i = 0; i < order.getHandleEmployeeNo().size(); i++) {
                JSONObject employeeJson = getEmployeeById(order.getHandleEmployeeNo().get(i));
                if (Objects.nonNull(employeeJson)) {
                    JSONArray depart = employeeJson.getJSONArray("departmentName");
                    if (Objects.nonEmpty(depart)){
                        departSet.addAll(JSONArray.parseArray(depart.toJSONString(), String.class));
                    }
                }
            }
            order.setHandleDepartName(new ArrayList<>(departSet));

            jdbcSession.insert(tempOrder);

            List<String> handleEmployee = tempOrder.getHandleEmployeeNo();
            if (Objects.nonEmpty(handleEmployee)) {
                handleEmployee.forEach(e -> notifyEmployee("1", e, tempOrder.getCreateUserNo(), tempOrder.getCreateUserName(), tempOrder.getName(), tempOrder.getId()));
            }
            List<String> noticeEmployee = tempOrder.getNoticeEmployeeNo();
            if (Objects.nonEmpty(noticeEmployee)) {
                noticeEmployee.forEach(e -> notifyEmployee("2", e, tempOrder.getCreateUserNo(), tempOrder.getCreateUserName(), tempOrder.getName(), tempOrder.getId()));
            }
        }
    }

    private JSONObject buildEmployee(String houseNo, String companyNo) {
        JSONObject result = new JSONObject();
        try {
            JSONObject buildingResult = doveClient.post("/basic/building/service/get", (http) -> {
                Map<String, String> map =new HashMap<>();
                map.put("companyNo", companyNo);
                http.setHeaders(map);
                JSONObject body = new JSONObject();
                body.put("id", houseNo);
                http.setBody(body.toJSONString());
            });

            if (buildingResult.getIntValue("code")== 200) {
                JSONObject buildingJson=buildingResult.getJSONObject("data");
                if(Objects.nonNull(buildingJson)){
                    List<String> employeeNos = JSONObject.parseArray(buildingJson.getJSONArray("employeeNos").toJSONString(),String.class);
                    List<String> employeeNames = new ArrayList<>();
                    Set<String> departs = new HashSet<>();
                    if(Objects.nonEmpty(employeeNos)){
                        Set<String> employeeIds = new HashSet<>(employeeNos);
                        Map<String,JSONObject> employeeMap = getEmployeeMap(new ArrayList<>(employeeIds));
                        for (String employeeNo : employeeNos) {
                            JSONObject employee = employeeMap.get(employeeNo);
                            if(Objects.nonNull(employee)){
                                employeeNames.add(employee.getString("name"));
                                if (Objects.nonEmpty(employee.getJSONArray("departmentName")))
                                    departs.addAll(employee.getJSONArray("departmentName").stream().map(String::valueOf).collect(Collectors.toSet()));
                            }
                        }
                        result.put("employeeNos", employeeIds.toArray());
                        result.put("employeeNames", employeeNames);
                        result.put("departs", departs.toArray());
                    }
                }
            }
        } catch (Exception e) {
            logger.error(e.getMessage(), e);
        } finally {
            return result;
        }
    }

    public Map<String,JSONObject> getEmployeeMap(List<String> employeeIds) throws Exception {
        JSONObject result = doveClient.post("/basic/employee/service/list", http->{
            JSONObject body = new JSONObject();
            body.put("id", employeeIds);
            body.put("pageNo", 1);
            body.put("pageSize", 1000000);
            http.setBody(body.toString());
        });

        JSONArray data = result.getJSONObject("data").getJSONArray("list");

        if (Objects.isNull(data)) {
            return null;
        }

        Map<String,JSONObject> employeeMap = new HashMap<>();
        data.forEach(item->{
            JSONObject obj = (JSONObject) item;
            employeeMap.put(obj.getString("id"), obj);
        });

        return employeeMap;
    }

    private void setWorkOrder(JSONObject json, WorkOrderManage tempOrder) {
        tempOrder.setTypeNo(json.getString("typeNo"));
        if (Objects.isEmpty(json.getString("typeName"))) {
            WorkOrderManageType type = Pool.get(WorkOrderManageType.class, tempOrder.getTypeNo());
            tempOrder.setTypeName(type.getName());
        } else {
            tempOrder.setTypeName(json.getString("typeName"));
        }
        tempOrder.setOneClassifyNo(json.getString("oneClassifyNo"));
        tempOrder.setOneClassifyName(json.getString("oneClassifyName"));
        tempOrder.setTwoClassifyNo(json.getString("twoClassifyNo"));
        tempOrder.setTwoClassifyName(json.getString("twoClassifyName"));
        tempOrder.setContent(json.getString("content"));
        tempOrder.setAddress(json.getString("address"));
        tempOrder.setProvinceCode(json.getString("provinceCode"));
        tempOrder.setCityCode(json.getString("cityCode"));
        tempOrder.setDistrictCode(json.getString("districtCode"));
        tempOrder.setLng(json.getString("lng"));
        tempOrder.setLat(json.getString("lat"));
        tempOrder.setSignIn(json.getBooleanValue("signIn"));
        tempOrder.setAddressDetail(json.getString("addressDetail"));
        tempOrder.setEmergency(Enums.getEnum(EmergencyStateEnum.class, json.getJSONObject("emergency").getString("id")));
        tempOrder.setDoorToDoor(Enums.getEnum(DoorToDoorEnum.class, json.getJSONObject("doorToDoor").getString("id")));
        tempOrder.setWorkOrderState(Enums.getEnum(WorkOrderStateEnum.class, json.getJSONObject("workOrderState").getString("id")));
        tempOrder.setDoorToDoorStartTime(json.getString("doorToDoorStartTime"));
        tempOrder.setDoorToDoorEndTime(json.getString("doorToDoorEndTime"));
        tempOrder.setHandlePositionTitle(json.getString("handlePositionTitle"));
        tempOrder.setAvatar(json.getString("avatar"));

        if (Objects.nonNull(json.getJSONArray("imgIds"))){
            tempOrder.setImgIds(JSONObject.parseArray(json.getJSONArray("imgIds").toString(), String.class));
        }
        if (Objects.nonNull(json.getJSONArray("handleEmployeeNo"))){
            tempOrder.setHandleEmployeeNo(JSONObject.parseArray(json.getJSONArray("handleEmployeeNo").toString(), String.class));
        }
        if (Objects.nonNull(json.getJSONArray("handleEmployeeName"))){
            tempOrder.setHandleEmployeeName(JSONObject.parseArray(json.getJSONArray("handleEmployeeName").toString(), String.class));
        }
        if (Objects.nonNull(json.getJSONArray("handleDepartName"))){
            tempOrder.setHandleDepartName(JSONObject.parseArray(json.getJSONArray("handleDepartName").toString(), String.class));
        }
        if (Objects.nonNull(json.getJSONArray("noticeEmployeeNo"))){
            tempOrder.setNoticeEmployeeNo(JSONObject.parseArray(json.getJSONArray("noticeEmployeeNo").toString(), String.class));
        }
        if (Objects.nonNull(json.getJSONArray("noticeEmployeeName"))){
            tempOrder.setNoticeEmployeeName(JSONObject.parseArray(json.getJSONArray("noticeEmployeeName").toString(), String.class));
        }


        Set<String> set = new HashSet<>();
        Set<String> authorityUserSet = new HashSet<>();
        if (Objects.nonEmpty(tempOrder.getHandleEmployeeNo())){
            set.addAll(tempOrder.getHandleEmployeeNo());
            authorityUserSet.addAll(tempOrder.getHandleEmployeeNo());
        }
        if (Objects.nonEmpty(tempOrder.getNoticeEmployeeNo())){
            authorityUserSet.addAll(tempOrder.getNoticeEmployeeNo());
        }
        authorityUserSet.add(tempOrder.getCreateUserNo());
        tempOrder.setSubmitToMeNo(new ArrayList<>(set));
        tempOrder.setAuthorityUserList(new ArrayList<>(authorityUserSet));

        // tempOrder.setSubmitToMeNo(tempOrder.getHandleEmployeeNo());
        // tempOrder.setSubmitToMeName(tempOrder.getHandleEmployeeName());

        if (Objects.nonEmpty(tempOrder.getTwoClassifyName())) {
            tempOrder.setName(tempOrder.getTwoClassifyName());
        } else {
            tempOrder.setName(tempOrder.getOneClassifyName());
        }
    }

    private void initWorkOrder(WorkOrderManage tempOrder) {
        tempOrder.setId(IDGenerate.nextId());
        tempOrder.setCreateTime(TimeUtil.timestamp());
        tempOrder.setUpdateTime(TimeUtil.timestamp());
        tempOrder.setWorkOrderState(WorkOrderStateEnum.ING);
        tempOrder.setFinishTime(null);
        tempOrder.setUserAppraisal(false);
        tempOrder.setRecordId(null);
    }

    private void setHandleDepart(WorkOrderManage order) {
        Set<String> departSet = new HashSet<>();
        for (int i = 0; i < order.getHandleEmployeeNo().size(); i++) {
            JSONObject employeeJson = getEmployeeById(order.getHandleEmployeeNo().get(i));
            if (Objects.nonNull(employeeJson)) {
                JSONArray depart = employeeJson.getJSONArray("departmentName");
                if (Objects.nonEmpty(depart)){
                    departSet.addAll(JSONArray.parseArray(depart.toJSONString(), String.class));
                }
            }
        }
        order.setHandleDepartName(new ArrayList<>(departSet));
    }

    /**
     * 获取最近节点记录
     * @param id recordId
     * @return
     */
    private WorkOrderManageRecord getNodeRecord(String id) {
        WorkOrderManageRecord record = Pool.get(WorkOrderManageRecord.class, id);
        if (record.isNode() || Objects.isEmpty(record.getParentRecordId())) {
            return record;
        }

        return getNodeRecord(record.getParentRecordId());
    }

    /**
     * 获取上一节点记录
     * @param recordId
     * @return
     */
    private WorkOrderManageRecord getParentNodeRecord(String recordId) {
        WorkOrderManageRecord record = Pool.get(WorkOrderManageRecord.class, recordId);
        if (Objects.isEmpty(record.getParentRecordId())) {
            return record;
        }

        WorkOrderManageRecord parentRecord = Pool.get(WorkOrderManageRecord.class, record.getParentRecordId());
        if (Objects.isEmpty(parentRecord.getParentRecordId())) {
            return parentRecord;
        }

        return getNodeRecord(record.getParentRecordId());
    }

    private JSONObject buildHandleUserJson(WorkOrderManage order, String handleUserNo, String handleUserName) {
        JSONObject jsonObject = createNextEmployee(order);
        jsonObject.put("handleUserNo", handleUserNo);
        jsonObject.put("handleUserName", handleUserName);
        return jsonObject;
    }

    private String insertRecord(JSONObject json, WorkOrderManage order,WorkOrderHandleStateEnum handleState, boolean resetLastCreateTime, boolean userCreate) {
        WorkOrderManageRecord record = Pool.newInstance(WorkOrderManageRecord.class);
        record.setWorkOrderId(order.getId());
        record.setParentRecordId(order.getRecordId());
        record.setHandleState(handleState);
        record.setName(order.getName());
        record.setRemark(json.getString("remark"));
        record.setAddress(json.getString("address"));
        record.setLng(json.getString("lng"));
        record.setLat(json.getString("lat"));
        record.setNode(true);
        record.setUserCreate(userCreate);
        record.setNextEmployeeNo(json.getString("nextUserNo"));
        record.setNextEmployeeName(json.getString("nextUserName"));
        record.setHandlePositionTitle(json.getString("handlePositionTitle"));
        record.setAvatar(json.getString("avatar"));
        if (Objects.nonEmpty(json.getJSONArray("imgIds"))){
            record.setImgIds(JSONObject.parseArray(json.getJSONArray("imgIds").toString(), String.class));
        }
        record.setHandleEmployeeNo(json.getString("handleUserNo"));
        record.setHandleEmployeeName(json.getString("handleUserName"));

        record.setLastCreateTime(TimeUtil.timestamp());
        if (Objects.nonEmpty(order.getRecordId())) {
            WorkOrderManageRecord parentRecord = Pool.get(WorkOrderManageRecord.class, order.getRecordId());
            record.setLastCreateTime(parentRecord.getCreateTime());

            if (resetLastCreateTime) {
                record.setLastCreateTime(parentRecord.getLastCreateTime());
                record.setNode(false);
            }
        }

        jdbcSession.insert(record);

        return record.getId();
    }

    public Object reminders(String id){
        WorkOrderManage order = Pool.get(WorkOrderManage.class, id);
        WorkOrderManageReminders reminders = Pool.get(WorkOrderManageReminders.class, id);
        if (Objects.isNull(reminders)) {
            reminders = Pool.newInstance(WorkOrderManageReminders.class, id);
            jdbcSession.insert(reminders);
            sendReminds(order);
            return Result.success();
        }

        if (reminders.getUpdateTime().toLocalDateTime().plusHours(4L).isBefore(LocalDateTime.now())){
            jdbcSession.updateById(reminders);
            sendReminds(order);
            return Result.success();
        } else {
            return Result.error(0, "您好，需要4小时后才能再次催办");
        }
    }

    private void sendReminds(WorkOrderManage order) {
        List<String> handleEmployee = order.getHandleEmployeeNo();
        handleEmployee.forEach(e -> {
            try {
                msgUniformSend(order, e, TemplateType.WO_B_URGE, false);
            } catch (Exception exception) {
                logger.error(exception.getMessage(), exception);
            }
        });
    }

    public Object signInList(JSONObject jsonObject) {
        return Result.success(jdbcSession.findPage(WorkOrderManageRecord.class)
                                                          .eq(jsonObject, "workOrderId")
                                                          .eq("handleState", WorkOrderHandleStateEnum.SIGN_IN)
                                                          .page(jsonObject)
                                                          .exe());
    }

    public Object signInDetail(String id) {
        return Result.success(Pool.get(WorkOrderManageRecord.class, id));
    }

    /**
     * <p>员工端提醒消息</p>
     * <p>{createUserName}{typeId}一个《{title}》指定由您处理/给您</p>
     * @param typeId 消息类型：1发起，2抄送，3催办
     * @param uuid 接收员工ID
     * @param createUserNo 工单创建人ID
     * @param createUserName 工单创建人
     * @param title 工单名称
     * @return
     */
    public void notifyEmployee(String typeId, String uuid, String createUserNo, String createUserName, String title, String msgId){
        try {
            doveClient.post("/crm/message/service/notify/employee", (http) -> {
                JSONObject type = new JSONObject();
                type.put("id", typeId);

                JSONObject body = new JSONObject();
                body.put("uuid", uuid);
                body.put("createUserNo", createUserNo);
                body.put("createUserName", createUserName);
                body.put("type", type);
                body.put("title", title);
                body.put("msgId", msgId);

                http.setBody(body.toString());
            });
        } catch (Exception e){
            logger.error(e.getMessage(), e);
        }
    }
}
